package com.itheima.service.impl;

import com.itheima.dao.MoneyLogDao;
import com.itheima.domain.MoneyLog;
import com.itheima.line.SessionThreadLocal;
import com.itheima.redission.DistributedLocker;
import com.itheima.service.MoneyLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/*****
 * @Author: http://www.itheima.com
 * @Description: com.itheima.service.impl.MoneyLogServiceImpl
 ****/
@Service
public class MoneyLogServiceImpl implements MoneyLogService {

    @Autowired
    private MoneyLogDao moneyLogDao;

    @Autowired
    private SessionThreadLocal sessionThreadLocal;

    @Autowired
    private RedisTemplate redisTemplate;



    /***
     * 查询用户的抢红包记录
     * @return
     */
    @Override
    public List<MoneyLog> list() {
        //去缓存中找数据
        List<MoneyLog> moneyLogs = (List<MoneyLog>) redisTemplate.boundHashOps("UserMoneyLog").get(sessionThreadLocal.get().getUsername());
        if(moneyLogs!=null){
            return moneyLogs;
        }
        //查询数据
        moneyLogs = moneyLogDao.list(sessionThreadLocal.get().getUsername());

        //如果有数据，则将数据存入到Redis
        redisTemplate.boundHashOps("UserMoneyLog").put(sessionThreadLocal.get().getUsername(),moneyLogs);
        return moneyLogs;
    }

    /***
     * 查询用户的抢红包记录
     * @param username
     * @return
     */
    @Override
    public List<MoneyLog> list(String username) {
        //查询数据
        return moneyLogDao.list(username);
    }

    /***
     * 获取排行数据
     */
    public List<MoneyLog> getTopList(String key){
        Object moneyLogs = redisTemplate.boundHashOps("UserMoneyLog").get(key);
        if(moneyLogs!=null){
            return (List<MoneyLog>) moneyLogs;
        }
        return null;
    }

    /***
     * 添加红包记录
     * @param moneyLog
     * @return
     */
    @Override
    public int add(MoneyLog moneyLog) {
        return moneyLogDao.add(moneyLog);
    }

    @Autowired
    private DistributedLocker distributedLocker;

    @Override
    public List<MoneyLog> top() {
        String key = "MoneyLogTop100";
        //从缓存中后去数据
        Object mlogs = redisTemplate.boundValueOps(key).get();
        if(mlogs==null){
            //先从缓存中查找数据，缓存如果没有数据，则查询数据库
            mlogs = moneyLogDao.top();

            //判断mlogs不为空，加入到缓存
            if(mlogs!=null){
                redisTemplate.boundValueOps(key).set(mlogs);
                redisTemplate.expire(key,1,TimeUnit.MINUTES);
            }
        }
        return (List<MoneyLog>) mlogs;
    }

    //分布式锁
    public List<MoneyLog> top_lock() {
        String key = "MoneyLogTop100";
        //从缓存中后去数据
        Object mlogs = redisTemplate.boundValueOps(key).get();
        if(mlogs==null){
            //控制用户操作，不要让所有用户直接操作数据库,获取锁
            Boolean bo = distributedLocker.lock("ITHEIMA", 10L, TimeUnit.SECONDS, 10L);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //拿到锁了，则查询数据库
            if(bo){
                System.out.println("18081获取锁--"+simpleDateFormat.format(new Date()));
                mlogs = redisTemplate.boundValueOps(key).get();
                if(mlogs==null){
                    //先从缓存中查找数据，缓存如果没有数据，则查询数据库
                    mlogs = moneyLogDao.top();

                    //判断mlogs不为空，加入到缓存
                    if(mlogs!=null){
                        redisTemplate.boundValueOps(key).set(mlogs);
                        redisTemplate.expire(key,1,TimeUnit.MINUTES);
                    }
                }
                //释放锁
                distributedLocker.unlock("ITHEIMA");
                System.out.println("18081释放锁--"+simpleDateFormat.format(new Date()));
            }
        }
        return (List<MoneyLog>) mlogs;
    }
}
